/**
 * 判断值真假
 * 1. 默认常规判断
 * 2. mode 含有 'zero' 时，数字0为真
 * 3. mode 含有 'arr' 时，空数组为假
 * 4. mode 含有 'obj' 时，空对象为假
 * 5. mode 含有 'bool' 时，false为真
 * 6. mode 含有 'strbo' 时，仅'true'或true为真，其他皆为假
 * @param {any} value 要判断的值
 * @param {string} mode 模式 可为包含 zero | arr 丨 obj 的字符串组合
 * @return {boolean} 判断结果
 */
export function isTruthy(value, mode = '') {
  let result = false
  // 常规真假判断
  result = !!value
  // 只有空格的字符串为假值
  if (typeof value === 'string' && !value.trim()) {
    result = false
  }
  // zero模式下数字0为真
  if (mode.includes('zero') && value === 0) {
    result = true
  }
  // arr模式下空数组为假值
  if (mode.includes('arr') && Array.isArray(value) && value.length === 0) {
    result = false
  }
  // obj模式下空对象为假值
  if (mode.includes('obj') && !Array.isArray(value) && typeof value === 'object' && value !== null && Object.keys(value).length === 0) {
    result = false
  }
  // bool模式下false为真
  if (mode.includes('bool') && value === false) {
    result = true
  }
  // strbo模式下仅'true'或true为真，其他皆为假
  if (mode.includes('strbo') && value !== 'true' && value !== true) {
    result = false
  }

  return result
}

/**
 * 获取变量类型
 * @param {any} val 要判断的变量
 * @returns {String} 类型
 */
export function isType(val) {
  const type = Object.prototype.toString.call(val)
  switch (type) {
    case '[object Boolean]':
      return 'boolean'
    case '[object Number]':
      return isNaN(val) ? 'NaN' : 'number' // 检测NaN
    case '[object String]':
      return 'string'
    case '[object Function]':
      return 'function'
    case '[object Array]':
      return 'array'
    case '[object Null]':
      return 'null' // 特殊处理null
    case '[object Undefined]':
      return 'undefined' // 特殊处理undefined
    default:
      return 'object' // 包括Date, RegExp, Error等都视为object
  }
}

/**
 * 判断变量是否是字符串型的数字
 * @param {any} val 要判断的变量
 * @returns {boolean} 是否是字符串型的数字
 */
export function isNumericString(val) {
  if (typeof val === 'string') {
    // 尝试将字符串转换为数字
    const num = parseFloat(val)
    // 如果转换后的结果不是NaN（不是数字），则说明是数字字符串
    return !isNaN(num)
  }
  return false
}

/**
 * 多元判断
 * @param {any} origin - 判断源
 * @param {Array<any>} conditions - 条件
 * @param {Array<any>} result - 处理结果
 * @return {any} - 对应的结果值或抛出错误
 */
export function multipleJudgment(origin, conditions = [], result = []) {
  // 检查条件和结果数组的长度是否一致
  if (conditions.length !== result.length) {
    throw new Error('条件数组和结果数组长度不一致')
  }

  // 查找判断源在条件数组中的位置
  const index = conditions.indexOf(origin)

  // 如果找到，则返回对应的结果值
  if (index !== -1) {
    return result[index]
  }

  // 如果没有找到，则返回本身
  return origin
}
